package com.guda.mp.web.base;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.app.core.common.AppBizCache;
import com.app.core.common.NoData;
import com.app.core.common.Result;
import com.app.core.util.SysConfig;
import com.app.core.web.filter.SysLogInterceptor;
import com.app.core.web.util.AppContextUtil;
import com.guda.mp.entity.SysDict;
import com.guda.mp.service.SysDictService;
import com.guda.mp.vo.SysDictVo;

/**
 * 
 * spring 容器初始化后监听器
 * 
 * @since v0.1
 * @author zxf
 * @created 2015年6月2日 下午2:42:27
 */
public class ApplicationListener implements ServletContextListener {

    private static final Logger log = LoggerFactory.getLogger(ApplicationListener.class);

    public void contextInitialized(ServletContextEvent contextEvent) {
        /* 把spring context已用存放到AppContextUtil */
        ServletContext sc = contextEvent.getServletContext();
        WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc);
        AppContextUtil.setContext(wac);

        /* 读取 配置文件 */
        readAppConfigFile();

        /* 加载解析系统配置文件 */
        loadAppConfig(wac);

        // 加载鲁尔中间库数据的设备id
        loadLuerTransferDbDevice();

        log.info("init end.");
    }

    /** 读取 配置文件 */
    private static void readAppConfigFile() {
        try {
            URL url = ResourceUtils.getURL("classpath:SysConfig.properties");
            SysConfig.loadProperties(url);
            // Set<Object> keySet = SysConfig.CONFIG.keySet();
            // for (Object key : keySet) {
            // log.warn(key + "=" + SysConfig.get((String) key));
            // }
        } catch (FileNotFoundException e) {
            log.error("加载SysConfig.properties失败。", e);
        }
    }

    /** 加载解析系统配置文件 */
    public static void loadAppConfig(WebApplicationContext wac) {
        ServletContext sc = wac.getServletContext();
        readAppConfigFile();

        // 把base放到上下文中
        sc.setAttribute("base", sc.getContextPath());
        sc.setAttribute("path", sc.getContextPath());
        sc.setAttribute("cpath", sc.getContextPath() + "/" + SysConfig.get("app.cpath"));
        sc.setAttribute("appName", SysConfig.get("app.name"));
        sc.setAttribute("staticVersion", SysConfig.get("js.staticVersion"));
        sc.setAttribute("qrcodeUrl", SysConfig.get("qrcode.url"));

        // 初始化数据字典
        intDictFromDB();
        // 日志路径配置
        initLogModule();
        // 网站基本数据配置
        initBaseDataConfig();
    }

    private static void initBaseDataConfig() {
        try {
            URL url = ResourceUtils.getURL("classpath:data/base_data_config.json");
            String data = FileUtils.readFileToString(new File(url.getFile()), "utf-8");
            AppBizCache.baseConfig = JSON.parseObject(data, JSONObject.class);
        } catch (Exception e) {
            log.error("加载classpath:biz_dict.json失败。", e);
        }
    }

    @SuppressWarnings("unused")
    public static void intDictFromJsonFile() {
        try {
            SysDictService sysDictService = AppContextUtil.getSpringBean("sysDictServiceImpl");
            List<SysDictVo> dictList = sysDictService.select(new SysDictVo());

            URL url = ResourceUtils.getURL("classpath:data/biz_dict.json");
            String data = FileUtils.readFileToString(new File(url.getFile()), "utf-8");
            AppBizCache.initDict(data);
        } catch (Exception e) {
            log.error("加载classpath:biz_dict.json失败。", e);
        }
    }

    public static Result<NoData> intDictFromDB() {
        try {
            SysDictService sysDictService = AppContextUtil.getSpringBean("sysDictServiceImpl");
            SysDictVo queryVo = new SysDictVo();
            queryVo.setStatus(1);
            List<SysDictVo> dictVOList = sysDictService.select(queryVo);
            List<SysDict> dictList = new ArrayList<SysDict>();
            for (SysDictVo sysDictVo : dictVOList) {
                SysDict sysDict = new SysDict();
                sysDict.setId(sysDictVo.getId());
                sysDict.setPid(sysDictVo.getPid());
                sysDict.setName(sysDictVo.getName());
                sysDict.setCode(sysDictVo.getCode());
                sysDict.setType(sysDictVo.getType());
                dictList.add(sysDict);
            }

            synchronized (sysDictService) {
                AppBizCache.initDictDB(dictList);
            }
        } catch (Exception e) {
            log.error("加载classpath:biz_dict.json失败。", e);
            return Result.error("操作失败: " + e.getMessage());
        }

        return Result.success();
    }

    private static void initLogModule() {
        try {
            URL url = ResourceUtils.getURL("classpath:logModule.json");
            String data = FileUtils.readFileToString(new File(url.getFile()), "utf-8");

            JSONArray jsonArray = JSON.parseArray(data);

            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                SysLogInterceptor.LOG_MAP.put(jsonObject.getString("url"), jsonObject);
            }
        } catch (Exception e) {
            log.error("加载classpath:logModule.json失败。", e);
        }
    }

    /** 读取 配置文件 */
    private static void loadLuerTransferDbDevice() {
        try {
            URL url = ResourceUtils.getURL("classpath:data/luer_transfer_db_device.txt");
            List<String> deviceSnList = FileUtils.readLines(new File(url.getFile()), "utf-8");
            Map<Long, String> luerTransferDeviceSnMap = new HashMap<>();
            for (String row : deviceSnList) {
                if (StringUtils.isNotBlank(row)) {
                    luerTransferDeviceSnMap.put(Long.valueOf(row), null);
                }
            }

            AppBizCache.luerTransferDeviceSnMap = luerTransferDeviceSnMap;
        } catch (IOException e) {
            log.error("加载loadLuerTransferDbDevice失败.", e);
        }
    }

    public void contextDestroyed(ServletContextEvent contextEvent) {
    }
}
